package com.sg.fileService.util;

import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncoderException;
import it.sauronsoftware.jave.EncodingAttributes;
import it.sauronsoftware.jave.InputFormatException;
import it.sauronsoftware.jave.MultimediaInfo;
import it.sauronsoftware.jave.VideoSize;
import lombok.extern.slf4j.Slf4j;

import java.io.File;

import com.sg.fileService.model.EnumSize;
import com.sg.fileService.config.Property;

/**
 * 音视频转换-音视频转化抽象类
 * 
 * @author xzk
 * @version 1.0
 * @date 20180224
 *
 */
@Slf4j
public abstract class AbsAVEncoder {
	// 格式化格式
	protected String format = "";
	// 文件后缀
	protected String fileSuffix = "";

	public AbsAVEncoder(String format, String suffix) {
		this.format = format;
		this.fileSuffix = suffix;
	}

	/**
	 * 视屏转换参数设置
	 * 
	 * @param videoSize
	 *            AVEncoder.MINI_VIDEO-最小分辨率，AVEncoder.MIDDLE_VIDEO-中等分辨率，AVEncoder.BIG_VIDEO-最大分辨率
	 * @throws IllegalArgumentException
	 * @throws InputFormatException
	 * @throws EncoderException
	 */
	public abstract EncodingAttributes initEncodeAttr(VideoSize videoSize);

	/**
	 * 视屏转换
	 * 
	 * @param sourceFilePath
	 * @param videoSizeType
	 *            AVEncoder.MINI_VIDEO-最小分辨率，AVEncoder.MIDDLE_VIDEO-中等分辨率，AVEncoder.BIG_VIDEO-最大分辨率
	 * @throws IllegalArgumentException
	 * @throws InputFormatException
	 * @throws EncoderException
	 */
	public void encoderVideo(String sourceFilePath, EnumSize videoSizeType) {

		// 如果videoSize为null表示源分辨率
		VideoSize videoSize = getVideoSize(videoSizeType);
		// 设置视屏转换参数
		EncodingAttributes attrs = initEncodeAttr(videoSize);

		// 源文件路径
		File source = new File(sourceFilePath);
		// 转换视屏文件保存路径
		File target = new File(getVideoTargetPath(sourceFilePath, videoSizeType));

		// 实例化转换器
		Encoder encoder = new Encoder();
		// 同步执行
		Long startTime = System.currentTimeMillis();
		// 转换前日志记录
		if (videoSize == null) {
			MultimediaInfo videoInfo;
			try {
				videoInfo = encoder.getInfo(source);
				log.info("原分辨率{}*{}开始转换------>开始时间{}", videoInfo.getVideo().getSize().getWidth(),
						videoInfo.getVideo().getSize().getHeight(), startTime);
			} catch (EncoderException e) {
				log.error(e.getMessage());
			}

		} else {
			log.info("分辨率:{}*{}开始转换------>开始时间{}", videoSize.getWidth(), videoSize.getHeight(), startTime);
		}
		try {
			encoder.encode(source, target, attrs);
		} catch (IllegalArgumentException | EncoderException e) {
			log.error(e.getMessage());
		}
		Long endTime = System.currentTimeMillis();
		// 转换后日志记录
		log.info("转换成功------->结束时间{}，耗时:{}秒", endTime, (endTime - startTime) / 1000);

	}

	/**
	 * 音屏转换
	 * 
	 * @param sourceFilePath
	 * @throws IllegalArgumentException
	 * @throws InputFormatException
	 * @throws EncoderException
	 */
	public void encoderAudio(String sourceFilePath){

		// 设置视屏转换参数
		EncodingAttributes attrs = initEncodeAttr(null);

		// 源文件路径
		File source = new File(sourceFilePath);
		// 转换视屏文件保存路径
		File target = new File(getAudioTargetPath(sourceFilePath));

		// 实例化转换器
		Encoder encoder = new Encoder();
		// 同步执行
		Long startTime = System.currentTimeMillis();

		log.info("音频开始转换------>开始时间{}", startTime);

		try {
			encoder.encode(source, target, attrs);
		} catch (IllegalArgumentException | EncoderException e) {
			log.error(e.getMessage());
		}
		Long endTime = System.currentTimeMillis();
		// 转换后日志记录
		log.info("转换成功------->结束时间{}，耗时:{}秒", endTime, (endTime - startTime) / 1000);

	}

	/**
	 * 根据转换视频分辨率的大小获取视频分辨率
	 * 
	 * @param videoSizeType
	 *            视频分辨大小类型
	 *            AVEncoder.MINI_VIDEO-最小分辨率，AVEncoder.MIDDLE_VIDEO-中等分辨率，AVEncoder.BIG_VIDEO-最大分辨率,EnumVideoSize.BREVIARY_IMG-缩略图
	 * @return
	 */
	public VideoSize getVideoSize(EnumSize videoSizeType) {
		VideoSize videoSize = null;

		if (EnumSize.MINI_SIZE == videoSizeType) {
			videoSize = new VideoSize(Property.V_MINI_WIDTH, Property.V_MINI_HEIGHT);
		} else if (EnumSize.MIDDLE_SIZE == videoSizeType) {
			videoSize = new VideoSize(Property.V_MIDDLE_WIDTH, Property.V_MIDDLE_HEIGHT);
		} else if (EnumSize.BIG_SIZE == videoSizeType) {
			if (Property.V_BIG_WIDTH != -1 && Property.V_BIG_HEIGHT != -1) {
				videoSize = new VideoSize(Property.V_BIG_WIDTH, Property.V_BIG_HEIGHT);
			}
		} else if (EnumSize.BREVIARY_IMG == videoSizeType) {
			videoSize = new VideoSize(Property.IMG_BREVIARY_WIDTH, Property.IMG_BREVIARY_HEIGHT);
		}
		return videoSize;
	}

	/**
	 * 获取视频转换保存路径
	 * 
	 * @param sourcePath
	 * @param videoSizeType
	 * @return
	 */
	public String getVideoTargetPath(String sourcePath, EnumSize videoSizeType) {

		sourcePath = getSourcePathWithSuffix(sourcePath);

		return PathCreator.getTargetFilePath(sourcePath, videoSizeType);
	}

	/**
	 * 获取音频转换保存路径
	 * 
	 * @param sourcePath
	 * @return
	 */
	public String getAudioTargetPath(String sourcePath) {

		return getVideoTargetPath(sourcePath, EnumSize.BIG_SIZE);

	}

	/**
	 * 获取视频/音频文件的信息
	 * 
	 * @param source
	 * @return
	 * @throws EncoderException
	 */
	public MultimediaInfo getInfo(File source) throws EncoderException {
		Encoder encoder = new Encoder();
		return encoder.getInfo(source);
	}

	/**
	 * 根据原路径拼接后缀
	 * 
	 * @param sourcePath
	 * @return
	 */
	private String getSourcePathWithSuffix(String sourcePath) {
		return PathCreator.modifyFileSuffix(sourcePath, this.fileSuffix);
	}

	public static void main(String args[]) {
	}
}
